﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using IronCow.UnitTests.Mock;
using NUnit.Framework.SyntaxHelpers;

namespace IronCow.UnitTests
{
    [TestFixture]
    public class TestContactGroups
    {
        [Test]
        public void TestEmptyContactGroup()
        {
            MockRtm rtm = new MockRtm();
            rtm.AddSuccessResponse("rtm.groups.getList",
                new MockGroupsResponsePart()
                {
                    new MockGroupResponsePart(1234, "Friends")
                });

            Assert.That(rtm.ContactGroups, Has.Count(1));
            ContactGroup contactGroup = rtm.ContactGroups[0];
            Assert.AreEqual("1234", contactGroup.Id);
            Assert.AreEqual("Friends", contactGroup.Name);
            Assert.That(contactGroup.Contacts, Has.Count(0));

            rtm.EnsureAllResponsesUsed();
        }

        [Test]
        public void TestMultipleEmptyContactGroups()
        {
            MockRtm rtm = new MockRtm();
            rtm.AddSuccessResponse("rtm.groups.getList",
                new MockGroupsResponsePart()
                {
                    new MockGroupResponsePart(1234, "Friends"),
                    new MockGroupResponsePart(2345, "Coworkers"),
                    new MockGroupResponsePart(3456, "Blocked")
                });

            Assert.That(rtm.ContactGroups, Has.Count(3));
            
            ContactGroup friendsGroup = rtm.ContactGroups[0];
            Assert.AreEqual("1234", friendsGroup.Id);
            Assert.AreEqual("Friends", friendsGroup.Name);
            Assert.That(friendsGroup.Contacts, Has.Count(0));

            ContactGroup coworkersGroup = rtm.ContactGroups[1];
            Assert.AreEqual("2345", coworkersGroup.Id);
            Assert.AreEqual("Coworkers", coworkersGroup.Name);
            Assert.That(coworkersGroup.Contacts, Has.Count(0));

            ContactGroup blockedGroup = rtm.ContactGroups[2];
            Assert.AreEqual("3456", blockedGroup.Id);
            Assert.AreEqual("Blocked", blockedGroup.Name);
            Assert.That(blockedGroup.Contacts, Has.Count(0));

            rtm.EnsureAllResponsesUsed();
        }

        [Test]
        public void TestContactGroupContacts()
        {
            MockRtm rtm = new MockRtm();
            rtm.AddSuccessResponse("rtm.groups.getList",
                new MockGroupsResponsePart()
                {
                    new MockGroupResponsePart(1234, "Staff", 1, 2)
                });
            rtm.AddSuccessResponse("rtm.contacts.getList",
                new MockContactsResponsePart()
                {
                    new MockContactResponsePart(1, "Omar Kilani", "omar"),
                    new MockContactResponsePart(2, "Emily Boyd", "emily"),
                    new MockContactResponsePart(3, "Bob T. Monkey", "bob")
                });

            Assert.That(rtm.ContactGroups, Has.Count(1));
            ContactGroup contactGroup = rtm.ContactGroups[0];
            Assert.AreEqual("1234", contactGroup.Id);
            Assert.AreEqual("Staff", contactGroup.Name);
            Assert.That(contactGroup.Contacts, Has.Count(2));

            Assert.That(rtm.Contacts, Has.Count(3));
            Assert.AreEqual("omar", rtm.Contacts[0].UserName);
            Assert.AreEqual("emily", rtm.Contacts[1].UserName);
            Assert.AreEqual("bob", rtm.Contacts[2].UserName);

            Assert.AreSame(rtm.Contacts[0], contactGroup.Contacts[0]);
            Assert.AreSame(rtm.Contacts[1], contactGroup.Contacts[1]);

            rtm.EnsureAllResponsesUsed();
        }

        [Test]
        public void TestAddContactToContactGroup()
        {
            MockRtm rtm = new MockRtm();
            rtm.AddSuccessResponse("rtm.groups.getList",
                new MockGroupsResponsePart()
                {
                    new MockGroupResponsePart(1234, "Staff", 1, 2)
                });
            rtm.AddSuccessResponse("rtm.contacts.getList",
                new MockContactsResponsePart()
                {
                    new MockContactResponsePart(1, "Omar Kilani", "omar"),
                    new MockContactResponsePart(2, "Emily Boyd", "emily"),
                    new MockContactResponsePart(3, "Bob T. Monkey", "bob")
                });
            rtm.AddTimelineResponse();
            rtm.AddSuccessResponse("rtm.groups.addContact");

            Assert.That(rtm.ContactGroups, Has.Count(1));
            ContactGroup contactGroup = rtm.ContactGroups[0];
            Assert.That(contactGroup.Contacts, Has.Count(2));

            Assert.That(rtm.Contacts, Has.Count(3));
            Assert.AreEqual("omar", rtm.Contacts[0].UserName);
            Assert.AreEqual("emily", rtm.Contacts[1].UserName);
            Assert.AreEqual("bob", rtm.Contacts[2].UserName);

            Contact bob = rtm.Contacts[2];
            contactGroup.Contacts.Add(bob);
            Assert.That(contactGroup.Contacts, Has.Count(3));

            Assert.AreSame(rtm.Contacts[0], contactGroup.Contacts[0]);
            Assert.AreSame(rtm.Contacts[1], contactGroup.Contacts[1]);
            Assert.AreSame(rtm.Contacts[2], contactGroup.Contacts[2]);

            rtm.EnsureAllResponsesUsed();
        }

        [Test]
        public void TestAddContactToContactGroupAddsContactToRtm()
        {
            MockRtm rtm = new MockRtm();
            rtm.AddSuccessResponse("rtm.contacts.getList",
                new MockContactsResponsePart()
                {
                    new MockContactResponsePart(1, "Omar Kilani", "omar"),
                    new MockContactResponsePart(2, "Emily Boyd", "emily")
                });
            rtm.AddSuccessResponse("rtm.groups.getList",
                new MockGroupsResponsePart()
                {
                    new MockGroupResponsePart(1234, "Staff", 1, 2)
                });
            rtm.AddTimelineResponse();
            rtm.AddSuccessResponse("rtm.contacts.add", new MockContactResponsePart(3, "Bob T. Monkey", "bob"));
            rtm.AddSuccessResponse("rtm.groups.addContact");

            Assert.That(rtm.Contacts, Has.Count(2));

            Assert.That(rtm.ContactGroups, Has.Count(1));
            ContactGroup contactGroup = rtm.ContactGroups[0];
            Assert.That(contactGroup.Contacts, Has.Count(2));

            Contact bob = new Contact("bob");
            Assert.That(string.IsNullOrEmpty(bob.FullName));
            contactGroup.Contacts.Add(bob);
            Assert.That(contactGroup.Contacts, Has.Count(3));
            Assert.That(rtm.Contacts, Has.Count(3));
            Assert.AreEqual("Bob T. Monkey", bob.FullName);

            Assert.AreSame(bob, rtm.Contacts[2]);
            Assert.AreSame(rtm.Contacts[0], contactGroup.Contacts[0]);
            Assert.AreSame(rtm.Contacts[1], contactGroup.Contacts[1]);
            Assert.AreSame(rtm.Contacts[2], contactGroup.Contacts[2]);

            rtm.EnsureAllResponsesUsed();
        }
    }
}
